package cn.bitkit.tools.net;

import cn.bitkit.base.util.StringUtil;
import cn.bitkit.tools.common.IOUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Cleanup;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 
 * @author changbo
 *
 */
@Slf4j
public class ServletUtil {
	
	public static final int DEFAULT_POST_MAX_LENGTH = 100000;
	public static final String AUTHORIZATION_KEY = "Authorization";
	public static final String AUTHORIZATION_START = "Bearer ";

	public static List<String> getParameterList(HttpServletRequest request, String key){
		String[] array = request.getParameterValues(key);
		if(array == null) {
			return List.of();
		}
		return List.of(array);
    }

	@SneakyThrows
    public static String readBody(HttpServletRequest request){
		@Cleanup
		BufferedReader reader = request.getReader();
		return IOUtil.readString(reader);
    }

	public static void returnText(HttpServletResponse response, String data){
		returnString(response, data, "text/plain");
	}

	public static void returnHtml(HttpServletResponse response, String data){
		returnString(response, data, "text/html");
	}

	@SneakyThrows
    public static void returnString(HttpServletResponse response, String data, String contextType){
		response.setCharacterEncoding("utf-8");
		response.setContentType(contextType);
		@Cleanup
		PrintWriter out = response.getWriter();
		out.write(data);
		out.flush();
    }

    public static void returnFile(HttpServletResponse response, byte[] bytes, String fileName){
    	returnFile(response, new ByteArrayInputStream(bytes), fileName);
    }

	@SneakyThrows
    public static void returnFile(HttpServletResponse response, InputStream is, String fileName){
    	setResponseFile(response, fileName);
		@Cleanup
		OutputStream out = response.getOutputStream();
		IOUtil.write(is, out);
		out.flush();
    }

    public static String getClientIp(HttpServletRequest request) {
		List<String> headerKey = List.of("x-forwarded-for"
				, "X-Real-IP"
				, "Proxy-Client-IP"
				, "WL-Proxy-Client-IP"
				, "HTTP_X_FORWARDED_FOR");
		String ip = headerKey.stream().map(request::getHeader)
				.filter(e -> StringUtil.hasValue(e) && !StringUtil.isEqual(e, "unknown"))
				.findFirst()
				.orElse(request.getRemoteAddr());
    	if(StringUtil.hasValue(ip) && ip.indexOf(",") > 0){
    		ip = ip.substring(0, ip.indexOf(","));
    	}
		return ip;
	}

    public static void setResponseFile(HttpServletResponse response, String fileName) {
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
    }
	
	public static String getAuthorization(HttpServletRequest request) {
        String authorization = request.getHeader(AUTHORIZATION_KEY);
        if(authorization.startsWith(AUTHORIZATION_START)) {
			return authorization.substring(AUTHORIZATION_START.length());
        }
		return authorization;
	}
    
}
